package host.springboot.framework.autoconfigure.filter;

import host.springboot.framework.autoconfigure.filter.properties.KsFilterProperties;
import host.springboot.framework.autoconfigure.filter.properties.children.KsRequestBodyWrapperProperties;
import host.springboot.framework.autoconfigure.filter.properties.children.KsXssProperties;
import host.springboot.framework.context.filter.RequestBodyFilter;
import host.springboot.framework.context.filter.XssFilter;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 过滤器自动配置类
 *
 * @author JiYinchuan
 * @since 1.0.0
 */
@Configuration(proxyBeanMethods = false)
@AutoConfiguration
@EnableConfigurationProperties({
        KsFilterProperties.class,
        KsRequestBodyWrapperProperties.class,
        KsXssProperties.class
})
public class KsFilterAutoConfiguration {

    /**
     * 请求体包装过滤器自动配置类
     *
     * @author JiYinchuan
     * @since 1.0.0
     */
    @AutoConfiguration
    @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
    @ConditionalOnProperty(
            prefix = KsRequestBodyWrapperProperties.KEY,
            name = "enabled",
            havingValue = "true",
            matchIfMissing = true)
    static class RequestBodyWrapperConfiguration {

        @Bean
        @ConditionalOnMissingBean
        public RequestBodyFilter.Config requestBodyFilterConfig() {
            return new RequestBodyFilter.Config();
        }

        @Bean
        @ConditionalOnMissingBean(RequestBodyFilter.class)
        public FilterRegistrationBean<RequestBodyFilter> requestBodyFilter(RequestBodyFilter.Config config) {
            FilterRegistrationBean<RequestBodyFilter> registrationBean = new FilterRegistrationBean<>();
            RequestBodyFilter requestBodyFilter = new RequestBodyFilter(config);
            registrationBean.setName("requestBodyFilter");
            registrationBean.setFilter(requestBodyFilter);
            registrationBean.addUrlPatterns("/*");
            registrationBean.setOrder(requestBodyFilter.getOrder());
            return registrationBean;
        }
    }

    /**
     * XSS攻击拦截自动配置类
     *
     * @author JiYinchuan
     * @since 1.0.0
     */
    @AutoConfiguration
    @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
    @ConditionalOnProperty(
            prefix = KsXssProperties.KEY,
            name = "enabled",
            havingValue = "true",
            matchIfMissing = true)
    static class XssFilterAutoConfiguration {

        @Bean
        @ConditionalOnMissingBean
        public XssFilter.Config xssFilterConfig() {
            return new XssFilter.Config();
        }

        @Bean
        @ConditionalOnMissingBean(XssFilter.class)
        public FilterRegistrationBean<XssFilter> xssFilter(XssFilter.Config config) {
            FilterRegistrationBean<XssFilter> registrationBean = new FilterRegistrationBean<>();
            XssFilter xssFilter = new XssFilter(config);
            registrationBean.setName("xssFilter");
            registrationBean.setFilter(xssFilter);
            registrationBean.addUrlPatterns("/*");
            registrationBean.setOrder(xssFilter.getOrder());
            return registrationBean;
        }
    }
}
